
#ifndef __MY_UTIL__
#define __MY_UTIL__
#include<iostream>
#include<fstream>
#include<string>
#include<unistd.h>
#include<sys/stat.h>
#include<memory>
#include<sstream>
#include<jsoncpp/json/json.h>

using namespace std;
namespace aod{
    class FileUtil//文件实用工具类设计
    {
        private:
            std ::string _name;//文件路径名称
        public:
        FileUtil(const string& name):_name(name){} //构造函数
        bool Exists()//判断文件是否存在
        {
            //access的F_OK是专门用来检测文件是否存在，存在返回0
            int ret = access(_name.c_str(),F_OK);
            if(ret!=0)
            {
                cout<<"file is not exists"<<endl;
                return false;
            }
            return true;
        }
        size_t Size()//获取文件的大小
        {
            if(this->Exists()==false)//先判断文件是否存在
            {
                return 0;
            }
            //stat接口用于获取文件属性，其中st_size就是文件大小的成员,获取成功返回0
            struct stat st;
            int ret = stat(_name.c_str(),&st);
            if(ret!=0)
            {
                cout<<"get file stat failed"<<endl;
                return 0;
            }
            return st.st_size;
        }
        bool GetContent(std::string *body)//读取文件数据到body
        {
            ifstream ifs;
            ifs.open(_name,ios::binary);//打开以二进制的方式读取数据
                if(ifs.is_open()==false)
                {
                    cout<<"open file failed!"<<endl;
                    return false;
                }
            size_t flen = this->Size();//获取文件大小
            body->resize(flen);//调整缓冲区大小
            ifs.read(&(*body)[0],flen);//(*body)解引用
            if(ifs.good()==false)
            {
                cout<<"read file failed!"<<endl;
                ifs.close();
                return false;
            }
            ifs.close();
            return true;
        }
        bool SetContent(const string&body)//向文件写入数据
        {
            ofstream ofs;
            ofs.open(_name,ios::binary);//打开以二进制的方式读取数据
            if(ofs.is_open()==false)
            {
                cout<<"open file failed!"<<endl;
                return false;
            }
            ofs.write(body.c_str(),body.size());//不能修改所以可以用c_str()
            if(ofs.good()==false)
            {
                cout<<"write file failed!"<<endl;
                ofs.close();
                return false;
            }
            ofs.close();
            return true;
        }
        bool CreateDirectory()//针对目录时创建目录
        {
            if (this->Exists()) {
                return true;
            }
            mkdir(_name.c_str(), 0777);
            return true;
        }
    };
    class JsonUtil//Json实用工具类设计
    {
        public:
          static bool Serialize(const Json::Value &value, std::string *body)//序列化
          {
            Json::StreamWriterBuilder swb;//智能指针头文件memory;StreamWriter不能直接使用只能通过StreamWriterBuilder来new一个接口实例化
            std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());//定义一个智能指针指向的对象是 Json::StreamWriter 来进行初始化

            std::stringstream ss;
            int ret = sw->write(value, &ss);//sw指向write进行序列化;如果ret返回为0则成功
            if(ret!=0)
            {
                 cout<<"serialize  failed"<<endl;
                 return false;
            }
            *body=ss.str();//如果序列化成功则返回一个字符串
            return true;
          }  
          static bool UnSerialize(const std::string &body,Json::Value *value)//反序列化
          {
            Json::CharReaderBuilder crb;
            std::unique_ptr<Json::CharReader> cr(crb.newCharReader());

            std::string err;
            bool ret = cr->parse(body.c_str(),body.c_str()+body.size(),value,&err);
            if(ret==false)
            {
                cout<<"unserialize failed"<<endl;
                return false;
            }
            return true;
          }
    };
    
}


#endif